import { api, TWsClient } from '@/assets/api'

const msg = {
    ac: 'feiScb',
    data: {
        devTime: 0,
        tplCode: '',
        params: {
            forceFlag: 0,
            matchId: 0,
            resultId: 0,
            scheduleDate: '',
            tsInfo: {},
            tag: {},
        },
    },
}

class TJumpScb {
    constructor() {
        this.api = api
        this.settings = {}
        this.scbInfo = {
            /*
                            schedule,
                            judge,
                            startList,
                            rank,
                            medal
                        */
            tplCode: '',
            matchId: 0,
            resultId: 0,
            scheduleDate: '',
        }
        this.times = {
            dev: new Date().getTime(),
            local: new Date().getTime(),
            recTsTime: 0,
            tplTime: 0,
        }
        this.scbData = {
            matchInfo: {},
            judge: [],
            schedule: [],
            startList: [],
            rank: [],
            medal: [],
            resultInfo: {},
            tsInfo: {},
            resultRank: [],
            matchRank: [],
        }
        this.events = {
            onSetMsg: (msg) => {},
        }
    };
    setMsg(msg) {
        var me = this
        try {
            me.setDevTime(msg.data.devTime)
            me.scbInfo.tplCode = msg.data.tplCode
            var onSetMsg = (_msg) => {
                if (me.events.onSetMsg != null) {
                    try {
                        me.events.onSetMsg(msg)
                    } catch (er) {}
                }
            }
            var paramKeys = Object.keys(msg.data.params)
            var forceFlag = msg.data.params.forceFlag > 0
            var index = 0
            var actionItem = () => {
                if (index < paramKeys.length) {
                    var pk = paramKeys[index]
                    if (pk == 'matchId') {
                        me.setMatchId(msg.data.params.matchId, forceFlag).then((_) => {
                            index = index + 1
                            actionItem()
                        })
                    } else if (pk == 'resultId') {
                        me.setResultId(msg.data.params.resultId, forceFlag).then((_) => {
                            index = index + 1
                            actionItem()
                        })
                    } else if (pk == 'scheduleDate') {
                        me.updateSchedule(msg.data.params.scheduleDate).then((_) => {
                            index = index + 1
                            actionItem()
                        })
                    } else if (pk == 'tsInfo') {
                        me.times.recTsTime = new Date().getTime()
                        me.scbData.tsInfo = msg.data.params.tsInfo;
                        me.scbData.tsInfo.lastMsgTime = (new Date()).getTime();
                        index = index + 1
                        actionItem()
                    } else if (pk == 'tag') {
                        me.scbData.tag = msg.data.params.tag
                        index = index + 1
                        actionItem()
                    } else {
                        index = index + 1
                        actionItem()
                    }
                } else {
                    onSetMsg(msg)
                }
            }
            actionItem()
        } catch (error) {
            if (me.events.onSetMsg != null) {
                try {
                    me.events.onSetMsg(msg)
                } catch (er) {}
            }
            console.log(error)
        }
    };
    //--------------------------------------------------------------------
    setDevTime(devTime) {
        var me = this
        try {
            me.times.dev = devTime
            me.times.local = new Date().getTime()
        } catch (error) {
            console.log(error)
        }
    };
    setMatchId(value, forceFlag = false) {
        var me = this
        return new Promise((su, fa) => {
            try {
                if (value != me.scbInfo.matchId || forceFlag) {
                    me.scbInfo.matchId = value
                    var matchTplCodes = ['judge', 'startList', 'rank', 'medal']
                    if (matchTplCodes.includes(me.scbInfo.tplCode)) {
                        var procName = 'proc_scb_' + me.scbInfo.tplCode
                        var ps = {
                            matchId: value,
                        }
                        me.updateMatchInfo(value)
                            .then((_) => {
                                return me.api.execProc(procName, ps)
                            })
                            .then((_res) => {
                                var resData = _res.datasetList[0]
                                me.scbData[me.scbInfo.tplCode] = resData
                                su()
                            })
                    }
                }
            } catch (er) {
                su()
                console.log(er)
            }
        })
    };
    setResultId(value, forceFlag = false) {
        var me = this
        return new Promise((su, fa) => {
            try {
                if (value != me.scbInfo.resultId || forceFlag) {
                    me.scbInfo.resultId = value
                    me.updateResultInfo(value)
                        .then((_) => {
                            var matchId = me.scbData.resultInfo.matchId
                            return me.updateMatchInfo(matchId)
                        }).then((_) => {
                            return me.updateResultRank(value)
                        })
                        .then((_res) => {
                            su()
                        })
                }
            } catch (er) {
                su()
                console.log(er)
            }
        })
    };
    updateMatchInfo(matchId) {
        var me = this
        return new Promise((su, fa) => {
            try {
                me.api.viewRows('vs_tsJump_matchSettigs', { matchId }).then((_res) => {
                    var matchInfo = _res.datasetList[0][0]
                    matchInfo.settings = {
                        t0: JSON.parse(matchInfo.settingsJsonT0),
                        t1: JSON.parse(matchInfo.settingsJsonT1),
                        t2: JSON.parse(matchInfo.settingsJsonT2),
                    }
                    me.scbData.matchInfo = matchInfo
                    console.log(me.scbData.matchInfo)
                    su()
                })
            } catch (er) {
                su()
                console.log(er)
            }
        })
    };
    updateResultInfo(resultId) {
        var me = this
        return new Promise((su, fa) => {
            try {
                me.api.viewRows('vs_tsJump_result', { resId1: resultId }).then((_res) => {
                    me.scbData.resultInfo = _res.datasetList[0][0]
                    console.log(me.scbData.resultInfo)
                    su()
                })
            } catch (er) {
                su()
                console.log(er)
            }
        })
    };
    updateSchedule(scheduleDate) {
        var me = this
        return new Promise((su, fa) => {
            try {
                me.scbInfo.scheduleDate = scheduleDate
                var procName = 'proc_scb_schedule'
                var ps = {
                    scheduleDate,
                }
                me.api.execProc(procName, ps).then((_res) => {
                    me.scbData.schedule = _res.datasetList[0]
                    su()
                })
            } catch (er) {
                su()
                console.log(er)
            }
        })
    };
    updateResultRank(resultId) {
        var me = this
        return new Promise((su, fa) => {
            try {
                // if (resultId != me.scbInfo.resultId) {
                // }
                var procName = 'Proc_TS_JumpRealResult'
                var ps = {
                    resultId,
                }
                me.api.execProc(procName, ps).then((_res) => {
                    me.scbData.resultRank = _res.datasetList[0]
                    me.scbData.matchRank = _res.datasetList[1]
                    su()
                })
            } catch (er) {
                su()
                console.log(er)
            }
        })
    };
    getCurrentClock() {
        var res = "";
        var me = this;
        try {
            var irmFlag = (me.scbData.tsInfo.t1.irm != '') || (me.scbData.tsInfo.t2.irm != '');
            if (irmFlag) {
                res = me.scbData.tsInfo.t1.irm != '' ? me.scbData.tsInfo.t1.irm : me.scbData.tsInfo.t2.irm;
            } else {
                var jumpStatus = me.jumpStatus;
                var maxT1 = parseInt(me.scbData.matchInfo.settings.t0.secondAllow);
                var limitT1 = parseInt(me.scbData.matchInfo.settings.t1.secondLimited);
                var limitT2 = parseInt(me.scbData.matchInfo.settings.t2.secondLimited);
                if (jumpStatus == 1000) {
                    res = me.scbData.matchInfo.settings.t0.secondAllow;
                } else if (jumpStatus == 1001) {
                    var lastMsgTime = me.scbData.tsInfo.lastMsgTime;
                    var nowTm = (new Date()).getTime();
                    var netTime = nowTm - lastMsgTime + me.scbData.tsInfo.t0.netTime;
                    if (netTime >= maxT1) {
                        res = "0";
                    } else {
                        res = Math.floor(0.001 * (maxT1 * 1000 - netTime)) + "";
                    }
                } else if (jumpStatus == 1002) {
                    res = Math.floor(0.001 * (maxT1 * 1000 - me.scbData.tsInfo.t0.netTime)) + "";
                } else if (jumpStatus == 1003) {
                    res = "0";
                } else if (jumpStatus == 1011) {
                    var lastMsgTime = me.scbData.tsInfo.lastMsgTime;
                    var nowTm = (new Date()).getTime();
                    var netTimeSecond = 0.001 * (nowTm - lastMsgTime + me.scbData.tsInfo.t1.netTime);
                    if (netTimeSecond < limitT1) {
                        res = (0.1 * Math.ceil(netTimeSecond * 10)).toFixed(1);
                    } else {
                        res = limitT1.toFixed(1);
                    }
                } else if (jumpStatus == 1012 || jumpStatus == 1013) {
                    if (me.scbData.tsInfo.t1.netTime < 1000 * limitT1) {
                        res = (0.01 * Math.ceil(0.1 * me.scbData.tsInfo.t1.netTime)).toFixed(2);
                    } else {
                        res = limitT1.toFixed(2);
                    }
                } else if (jumpStatus == 1021) {
                    var lastMsgTime = me.scbData.tsInfo.lastMsgTime;
                    var nowTm = (new Date()).getTime();
                    var netTimeSecond = 0.001 * (nowTm - lastMsgTime + me.scbData.tsInfo.t2.netTime);
                    if (netTimeSecond < limitT2) {
                        res = (0.1 * Math.ceil(netTimeSecond * 10)).toFixed(1);
                    } else {
                        res = limitT2.toFixed(1);
                    }
                } else if (jumpStatus == 1022 || jumpStatus == 1023) {
                    if (me.scbData.tsInfo.t2.netTime < 1000 * limitT2) {
                        res = (0.01 * Math.ceil(0.1 * me.scbData.tsInfo.t2.netTime)).toFixed(2);
                    } else {
                        res = limitT2.toFixed(2);
                    }
                }
            }
        } catch (er) {
            console.log(er)
        }
        return res;
    };
    getOverTimeScore(splitCode) {
        var res = {
            overTime: 0,
            overScore: 0
        };
        var me = this;
        try {
            var irmFlag = (me.scbData.tsInfo.t1.irm != '') || (me.scbData.tsInfo.t2.irm != '');
            if (!irmFlag) {
                var lastMsgTime = me.scbData.tsInfo.lastMsgTime;
                var nowTm = (new Date()).getTime();
                var netTime = 0;
                if([1011, 1021].includes(me.jumpStatus)) {
                  netTime = nowTm - lastMsgTime + me.scbData.tsInfo[splitCode].netTime;
                } else if (me.jumpStatus > 1011) {
                  netTime = me.scbData.tsInfo[splitCode].netTime;
                } else {
                  return res;
                }
                var allowMs = 1000 * me.scbData.matchInfo.settings[splitCode].secondAllow;
                if (netTime > allowMs) {
                    var limitedMs = 1000 * me.scbData.matchInfo.settings[splitCode].secondLimited;
                    var penScore = me.scbData.matchInfo.settings[splitCode].penTimeoutScore;
                    var penSecond = me.scbData.matchInfo.settings[splitCode].penTimeoutSecond;
                    if (netTime > limitedMs) {
                        res.overTime = limitedMs - allowMs;
                    } else {
                        res.overTime = netTime - allowMs;
                    }
                    var rate = Math.ceil(res.overTime / (1000.0 * penSecond));
                    res.overScore = rate * penScore;
                }
            }
        } catch (er) {
            console.log(er)
        }
        return res;
    };
    //--------------------------------------------------------------------
    get devNow() {
        var me = this
        var res = 0
        try {
            res = new Date().getTime() - me.times.local + me.times.dev
        } catch (error) {
            console.log(error)
        }
        return res
    };
    // 获取当前比赛状态 -- number
    get jumpStatus() {
        var me = this
        var res = 1000
        try {
            const tsInfo = me.scbData.tsInfo
            if (tsInfo.t0.status == 0) {
                res = 1000
            } else if (tsInfo.t0.status == 1 && tsInfo.t1.status == 0) {
                res = 1001
            } else if (tsInfo.t0.status == 2 && tsInfo.t1.status == 0) {
                res = 1002
            } else if (tsInfo.t0.status == 3 && tsInfo.t1.status == 0) {
                res = 1003
            } else if (tsInfo.t1.status == 1) {
                res = 1011
            } else if (tsInfo.t1.status == 2) {
                res = 1012
            } else if (tsInfo.t1.status == 3 && tsInfo.t2.status == 0) {
                res = 1013
            } else if (tsInfo.t2.status == 1) {
                res = 1021
            } else if (tsInfo.t2.status == 2) {
                res = 1022
            } else if (tsInfo.t2.status == 3) {
                res = 1023
            }
        } catch (er) {
            console.log(er)
        }
        return res
    };
    // 获取当前比赛状态
    get dispStatus() {
        var me = this
        var res = ''
        try {
            const tsInfo = me.scbData.tsInfo
            if (tsInfo.t0.status == 0) {
                res = 'notStart'
            } else if (tsInfo.t0.status == 1 && tsInfo.t1.status == 0) {
                res = 'start45'
            } else if (tsInfo.t0.status == 2 && tsInfo.t1.status == 0) {
                res = 'pause45'
            } else if (tsInfo.t0.status == 3 && tsInfo.t1.status == 0) {
                res = 'end45'
            } else if (tsInfo.t1.status == 1) {
                res = 'startP1'
            } else if (tsInfo.t1.status == 2) {
                res = 'pauseP1'
            } else if (tsInfo.t1.status == 3 && tsInfo.t2.status == 0) {
                res = 'endP1'
            } else if (tsInfo.t2.status == 1) {
                res = 'startP2'
            } else if (tsInfo.t2.status == 2) {
                res = 'pauseP2'
            } else if (tsInfo.t2.status == 3) {
                res = 'endP2'
            }
        } catch (er) {
            console.log(er)
        }
        return res
    };
    //基础数据
    get dispEventName() {
        var me = this
        var res = ''
        try {
            res = me.scbData.resultInfo.eventName
        } catch (er) {
            console.log(er)
        }
        return res
    };
    get dispMatchName() {
        var me = this
        var res = ''
        try {
            res = me.scbData.matchInfo.matchName
        } catch (er) {
            console.log(er)
        }
        return res
    };
    //总人数
    get dispResultNum() {
        var me = this
        var res = ''
        try {} catch (er) {
            console.log(er)
        }
        return res
    };
    get dispOrder() {
        var me = this
        var res = ''
        try {
            const status = me.dispStatus
            if (status.includes('P2')) {
                res = me.scbData.resultInfo.resOrder2
            } else {
                res = me.scbData.resultInfo.resOrder1
            }
        } catch (er) {
            console.log(er)
        }
        return res
    };
    get dispOrgName() {
        var me = this
        var res = ''
        try {
            res = me.scbData.resultInfo.orgName
        } catch (er) {
            console.log(er)
        }
        return res
    };
    get dispAthName() {
        var me = this
        var res = ''
        try {
            res = me.scbData.resultInfo.athName
        } catch (er) {
            console.log(er)
        }
        return res
    };
    get dispHorseName() {
        var me = this
        var res = ''
        try {
            res = me.scbData.resultInfo.horseName
        } catch (er) {
            console.log(er)
        }
        return res
    };
    get dispHorseBib() {
        var me = this
        var res = ''
        try {
            res = me.scbData.resultInfo.horseBib
        } catch (er) {
            console.log(er)
        }
        return res
    };
    // 障碍罚分数据
    get dispPenPoint() {
        var me = this
        var res = ''
        try {
            const tsInfo = me.scbData.tsInfo
            res = tsInfo.t1.penPoint + tsInfo.t2.penPoint
        } catch (er) {
            console.log(er)
        }
        return res
    };
    // 罚时数据
    get dispPenTime() {
        var me = this
        var res = 0
        try {
            var penScore = me.getOverTimeScore('t1').overScore + me.getOverTimeScore('t2').overScore;
            res = (0.1 * Math.ceil(penScore * 10)).toFixed(1);
        } catch (er) {
            console.log(er)
        }
        return res
    };
    // 本轮罚分
    get dispPenTotal() {
        var me = this
        var res = ''
        try {
            var totalScore = parseFloat(me.dispPenPoint) + parseFloat(me.dispPenTime);
            res = (0.1 * Math.ceil(totalScore * 10)).toFixed(1);
        } catch (er) {
            console.log(er)
        }
        return res
    };
    // 矫正时间
    get dispPenSecond() {
        var me = this
        var res = ''
        try {
            // 需确认是否需要累加
            //   const status = me.dispStatus
            //   if (status.includes('P2')) {
            //     res = me.scbData.tsInfo.t2.delaySecond
            //   } else {
            //     res = me.scbData.tsInfo.t1.delaySecond
            //   }
            res = me.scbData.tsInfo.t1.delaySecond + me.scbData.tsInfo.t2.delaySecond
        } catch (er) {
            console.log(er)
        }
        return res
    };
    //时钟、判罚
    get dispClockSecond() {
        var me = this
        var res = ''
        try {
            res = me.getCurrentClock();
            /*
            const tplCode = me.scbInfo.tplCode
            if (tplCode == 'irm') {
                res = me.dispIrm
            } else {
                const tsInfo = me.scbData.tsInfo
                const secondLimited1 = Number(me.scbData.matchInfo.settings.t1.secondLimited)
                const secondLimited2 = Number(me.scbData.matchInfo.settings.t2.secondLimited)
                const status = me.dispStatus
                if (status == 'notStart') {
                    res = ''
                } else if (status == 'start45') {
                    res = Math.max(0, 45 - Math.floor((me.times.local - me.times.recTsTime) / 1000))
                } else if (status == 'pause45') {
                    // 向下取整
                    res = Math.floor((45 * 1000 - tsInfo.t0.netTime) / 1000)
                } else if (status == 'end45') {
                    res = Math.floor((45 * 1000 - tsInfo.t0.netTime) / 1000)
                } else if (status == 'startP1') {
                    // 运行过程中展示1位小数
                    const runTime = (new Date().getTime() - me.times.recTsTime + tsInfo.t1.netTime) / 1000
                    const runTimeResult = Math.min(secondLimited1, runTime)
                    res = me.floorToFixed(runTimeResult, 1)
                } else if (['pauseP1', 'endP1'].includes(status)) {
                    // 暂停过程中展示2位小数
                    res = me.floorToFixed(Math.min(secondLimited1, tsInfo.t1.netTime / 1000), 2)
                } else if (status == 'startP2') {
                    // 运行过程中展示1位小数
                    const runTime = (new Date().getTime() - me.times.recTsTime + tsInfo.t2.netTime) / 1000
                    const runTimeResult = Math.min(secondLimited2, runTime)
                    res = me.floorToFixed(runTimeResult, 1)
                } else if (['pauseP2', 'endP2'].includes(status)) {
                    // 暂停过程中展示2位小数
                    res = me.floorToFixed(Math.min(secondLimited2, tsInfo.t2.netTime / 1000), 2)
                }
            }
                */
        } catch (er) {
            console.log(er)
        }
        return res
    };
    // 判罚
    get dispIrm() {
        var me = this
        var res = ''
        try {
          var irmFlag = (me.scbData.tsInfo.t1.irm != '') || (me.scbData.tsInfo.t2.irm != '');
          if (irmFlag) {
              res = me.scbData.tsInfo.t1.irm != '' ? me.scbData.tsInfo.t1.irm : me.scbData.tsInfo.t2.irm;
          } else {
              res = ''
          }
        } catch (er) {
            console.log(er)
        }
        return res
    };
    //与第1名的时间差
    get dispDltSecond() {
        var me = this
        var res = ''
        try {} catch (er) {
            console.log(er)
        }
        return res
    };
    // 该运动员排名
    get dispRealRank() {
        var me = this
        var res = ''
        try {
          if(me.jumpStatus <= 1003) {
            res = ''
          } else if (me.jumpStatus > 1003 && me.jumpStatus <= 1013){
            res = me.scbData.resultInfo.resRank1
          } else if (me.jumpStatus > 1013 && me.jumpStatus <= 1023){
            res = me.scbData.resultInfo.resRank2
          }
        } catch (er) {
            console.log(er)
        }
        return res
    };
    //排名（当前运动员最近的排名）
    get dispCurrentRank() {
        var me = this
        var res = []
        try {
            res = me.scbData.resultRank || []
        } catch (er) {
            console.log(er)
        }
        return res
    };
    // 排名（前3名）
    get dispRank3() {
        var me = this
        var res = []
        try {
          res = me.scbData.matchRank || []
        } catch (er) {
            console.log(er)
        }
        return res
    };

    /**
     * @desc 将毫秒转换为 HH:mm:ss.SSS 格式
     * @param {number} ms - 毫秒数
     * @param {boolean} [showMs=true] - 是否显示毫秒（默认显示）
     * @returns {string} 格式化后的时间字符串
     */
    formatTimeFromMs(ms, showMs = true) {
        if (typeof ms !== 'number' || isNaN(ms) || ms < 0) return '00:00:00'

        const totalSeconds = Math.floor(ms / 1000)
        const hours = Math.floor(totalSeconds / 3600)
        const minutes = Math.floor((totalSeconds % 3600) / 60)
        const seconds = totalSeconds % 60
        const milliseconds = ms % 1000

        const pad = (num, size = 2) => String(num).padStart(size, '0')

        return showMs ?
            `${pad(hours)}:${pad(minutes)}:${pad(seconds)}.${String(milliseconds).padStart(3, '0')}` :
            `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`
    };

    floorToFixed(num, decimals = 2) {
        const numStr = num.toString()
        const decimalIndex = numStr.indexOf('.')
        if (numStr.length === 0) {
            return '0'
        }
        if (decimalIndex === -1) {
            return num + '.' + '0'.repeat(decimals) // 整数直接补零
        }

        // 直接截取所需小数位
        const truncatedStr = numStr.substring(0, decimalIndex + decimals + 1)
        return parseFloat(truncatedStr).toFixed(decimals)
    };
}

export { TJumpScb }